#region Using directives

using System;
using System.Collections.Generic;
using System.Text;

using Weazel.Math;

#endregion

using System.IO;

namespace Weazel.Gezel.Simulator.Reference
{
  /// <summary>
  /// The FileSignal takes on its values from
  /// the numbers read in a file. The signal
  /// values are 128 bit signed integers
  /// </summary>
  class FileSignal : AbstractSignal
  {
    /// <summary>
    /// Stream to the file contents
    /// </summary>
    private StreamReader reader;

    /// <summary>
    /// Last value read from the stream
    /// </summary>
    private Integer value;

    /// <summary>
    /// Constructs a new FileSignal which reads
    /// its values from the file specified
    /// </summary>
    /// <param name="id"></param>
    /// <param name="filename">name of the file to read</param>
    public FileSignal(Symid id, string filename, string name) : base(id, name)
    {
      reader = new StreamReader(filename);
      // file signals have 128 bits of precision
      // and are signed as default
      value = new Integer(128, true);
    }

    /// <summary>
    /// Evaluate the signal by reading the next line from the file
    /// or returning the cached value in case of multiple evaluations
    /// in the same simulation cycle
    /// </summary>
    /// <param name="g"></param>
    /// <returns></returns>
    internal override Integer Evaluate(AbstractIpBlock ip, long g)
    {
      if (generation != g)
      {
        string line = reader.ReadLine();
        value.Assign(int.Parse(line.Trim())); // todo: use Integer instead
        generation = g;
      }

      // unfortunately this implies that, as soon as we use a FileSignal,
      // we will never be able to go into sleep mode
      // Simulation.sleep.CannotSleep();
      return value;
    }

    public override bool TraceToSignal(Symid toSignalId, List<AbstractSignal> signals)
    {
      return false;
    }
  }
}